{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dana\n"
     ]
    }
   ],
   "source": [
    "class Student ():\n",
    "    name = \"dana\"\n",
    "    age = 18\n",
    "    \n",
    "Student.__dict__\n",
    "\n",
    "# 实例化\n",
    "yueyue = Student()\n",
    "yueyue.__dict__\n",
    "print(yueyue.name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dana\n",
      "18\n",
      "********************\n",
      "139997501025056\n",
      "94068973276224\n",
      "********************\n",
      "dana\n",
      "18\n",
      "139997501025056\n",
      "94068973276224\n"
     ]
    }
   ],
   "source": [
    "class A():\n",
    "    name = \"dana\"\n",
    "    age = 18\n",
    "    \n",
    "    # 注意say的写法，参数由一个self\n",
    "    def say(self):\n",
    "        self.name = \"aaaa\"\n",
    "        self.age = 200\n",
    "        \n",
    "# 此案例说明\n",
    "# 类实例的属性和其对象的实例的属性在不对对象的实例属性赋值的前提下，\n",
    "# 指向同一个变量\n",
    "\n",
    "# 此时，A称为类实例\n",
    "print(A.name)\n",
    "print(A.age)\n",
    "\n",
    "print(\"*\" * 20)\n",
    "\n",
    "# id可以鉴别一个变量是否和另一个变量是同一变量\n",
    "print(id(A.name))\n",
    "print(id(A.age))\n",
    "\n",
    "print(\"*\" * 20)\n",
    "a = A()\n",
    "\n",
    "print(a.name)\n",
    "print(a.age)\n",
    "print(id(a.name))\n",
    "print(id(a.age))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dana\n",
      "18\n",
      "********************\n",
      "139997501025056\n",
      "94068973276224\n",
      "********************\n",
      "{'__module__': '__main__', 'name': 'dana', 'age': 18, 'say': <function A.say at 0x7f53b4c96e18>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}\n",
      "{}\n",
      "{'name': 'yaona', 'age': 16}\n",
      "yaona\n",
      "16\n",
      "139997492161816\n",
      "94068973276160\n"
     ]
    }
   ],
   "source": [
    "# 此时，A称为类实例\n",
    "print(A.name)\n",
    "print(A.age)\n",
    "\n",
    "print(\"*\" * 20)\n",
    "\n",
    "# id可以鉴别一个变量是否和另一个变量是同一变量\n",
    "print(id(A.name))\n",
    "print(id(A.age))\n",
    "\n",
    "print(\"*\" * 20)\n",
    "a = A()\n",
    "# 查看A内所有的属性\n",
    "print(A.__dict__)\n",
    "print(a.__dict__)\n",
    "\n",
    "a.name = \"yaona\"\n",
    "a.age = 16\n",
    "print(a.__dict__)\n",
    "\n",
    "print(a.name)\n",
    "print(a.age)\n",
    "print(id(a.name))\n",
    "print(id(a.age))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "My name is aaaa\n",
      "My age is 200\n",
      "My name is aaaa\n",
      "My age is 200\n"
     ]
    }
   ],
   "source": [
    "class Student():\n",
    "    name = \"dana\"\n",
    "    age = 18\n",
    "    \n",
    "    # 注意say的写法，参数由一个self\n",
    "    def say(self):\n",
    "        self.name = \"aaaa\"\n",
    "        self.age = 200\n",
    "        print(\"My name is {0}\".format(self.name))\n",
    "        print(\"My age is {0}\".format(self.age))\n",
    "    \n",
    "    def sayAgain(s):\n",
    "\n",
    "        print(\"My name is {0}\".format(s.name))\n",
    "        print(\"My age is {0}\".format(s.age))\n",
    "        \n",
    "yueyue = Student()\n",
    "yueyue.say()\n",
    "yueyue.sayAgain()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "My name is yaona\n",
      "My age is 19\n",
      "dana\n",
      "19\n",
      "Hello,nice to see you again\n"
     ]
    }
   ],
   "source": [
    "class Teacher():\n",
    "    name = \"dana\"\n",
    "    age = 19\n",
    "    \n",
    "    def say(self):\n",
    "        self.name = \"yaona\"\n",
    "        self.age = 17\n",
    "        print(\"My name is {0}\".format(self.name))\n",
    "        # 调用类的成员变量需要用__class__\n",
    "        print(\"My age is {0}\".format(__class__.age))\n",
    "    def sayAgain():\n",
    "        print(__class__.name)\n",
    "        print(__class__.age)\n",
    "        print(\"Hello,nice to see you again\")\n",
    "        \n",
    "t = Teacher()\n",
    "t.say()\n",
    "# 调用绑定类函数使用类名\n",
    "Teacher.sayAgain()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "aaaa\n",
      "200\n",
      "aaaa\n",
      "200\n",
      "liuying\n",
      "18\n",
      "bbbb\n",
      "90\n"
     ]
    }
   ],
   "source": [
    "# 关于self的案例\n",
    "\n",
    "class A():\n",
    "    name = \"liuying\"\n",
    "    age = \"18\"\n",
    "    \n",
    "    def __init__(self):\n",
    "        self.name = \"aaaa\"\n",
    "        self.age = 200\n",
    "        \n",
    "    def say(self):\n",
    "        print(self.name)\n",
    "        print(self.age)\n",
    "\n",
    "class B():\n",
    "    name = \"bbbb\"\n",
    "    age = 90\n",
    "    \n",
    "a = A()\n",
    "# 此时，系统会默认把a作为第一个参数传入函数\n",
    "a.say()\n",
    "\n",
    "# 此时，self被a替换\n",
    "A.say(a)\n",
    "\n",
    "# 同样可以把A作为参数传入\n",
    "A.say(A)\n",
    "\n",
    "# 此时，传入的是类实例B，因为B具有name和age属性，所以不会报错\n",
    "A.say(B)\n",
    "\n",
    "# 以上代码，利用了鸭子模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "liuying\n"
     ]
    },
    {
     "ename": "AttributeError",
     "evalue": "'Person' object has no attribute '__age'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-28-8de1e74f5750>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     11\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     12\u001b[0m \u001b[0;31m# __age是私有变量\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 13\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__age\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m: 'Person' object has no attribute '__age'"
     ]
    }
   ],
   "source": [
    "# 私有变量案例\n",
    "\n",
    "class Person():\n",
    "    # name是公有的成员\n",
    "    name = \"liuying\"\n",
    "    # __age就是私有成员\n",
    "    __age = 18\n",
    "    \n",
    "p = Person()\n",
    "# name是公有变量\n",
    "print(p.name)\n",
    "# __age是私有变量\n",
    "# 注意报错信息\n",
    "print(p.__age)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'__module__': '__main__', 'name': 'liuying', '_Person__age': 18, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}\n",
      "19\n"
     ]
    }
   ],
   "source": [
    "# name mangling技术\n",
    "print(Person.__dict__)\n",
    "\n",
    "p._Person__age = 19\n",
    "print(p._Person__age)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
